import threading
from  pymilvus import connections,db 
from conf.env import *
from pymilvus import Collection,CollectionSchema
from pymilvus import MilvusClient,DataType

class MilvusUtil():

    _instance_lock = threading.Lock()
    def __init__(self):
        url = "http://" + MILVUS_HOST + ":" + str(MILVUS_PORT)
        self.client = MilvusClient(uri=url,db_name=MILVUS_DB)
        # self.client = None
        

    def __new__(cls, *args, **kwargs):
        if not hasattr(MilvusUtil, "_instance"):
            with MilvusUtil._instance_lock:
                if not hasattr(MilvusUtil, "_instance"):
                    # 类加括号就回去执行__new__方法，__new__方法会创建一个类实例：Singleton()
                    MilvusUtil._instance = object.__new__(cls, *args, **kwargs)  # 继承object类的__new__方法，类去调用方法，说明是函数，要手动传cls
        return MilvusUtil._instance
    
    
    def search(self,collection_name,query,top_k,radius,range_filter,filter):
        search_params = {
            "params": {
                "radius": radius, # Radius of the search circle
                "range_filter": range_filter # Range filter to filter out vectors that are not within the search circle
            }
        }

        res = self.client.search(
            collection_name=collection_name,
            data=query,
            limit=top_k, # Max. number of search results to return    
            search_params= search_params,
            filter=filter
        )
        return res
    
    
    def search1(self,collection_name,query,top_k):
        # search_params = {
        #     "params": {
        #         "radius": radius, # Radius of the search circle
        #         "range_filter": range_filter # Range filter to filter out vectors that are not within the search circle
        #     }
        # }
        res = self.client.search(
            collection_name=collection_name,
            data=query,
            limit=top_k, # Max. number of search results to return  
            output_fields= ["id","context"]  
            # search_params= search_params,
        )
        return res
    
    def search(self,collection_name,query,top_k,radius,range_filter):
        search_params = {
            "params": {
                "radius": radius, # Radius of the search circle
                "range_filter": range_filter # Range filter to filter out vectors that are not within the search circle
            }
        }

        res = self.client.search(
            collection_name=collection_name,
            data=query,
            limit=top_k, # Max. number of search results to return    
            search_params= search_params
        )
        return res
    
    def upset(self,collection_name,data):
        res = self.client.upsert(
            collection_name=collection_name,
            data=data
        )
        return res
    
    def delete(self,collection_name,ids):
        res = self.client.delete(
            collection_name=collection_name,
            ids=ids
        )
        return res
    def create_schema(self):
        return self.client.create_schema(
            auto_id=False,
            enable_dynamic_field=True,
        )
        
    def prepare_index_params(self):
        return self.client.prepare_index_params()     
    
    def createTableAndIndex(self,collection_name,schema,index_params):
        self.client.create_collection(
            collection_name=collection_name,
            schema=schema,
            index_params=index_params
        )
    def createTableNoschema(self,collection_name,dimension):
        self.client.create_collection(
            collection_name=collection_name,  # 表名
            dimension=dimension,   # 向量维度
            auto_id=True,
            enable_dynamic_field=True
        )
    
    def createTable(self,collection_name,schema):       
        connections.connect("default", host="127.0.0.1", port="19530")
        Collection(name=collection_name, schema=schema)
    
    def dropTable(self,collection_name):
        try:
            print('删除milvus中的表'+collection_name)
            self.client.release_collection(collection_name)
            return self.client.drop_collection(collection_name)
        except Exception as e:
            print(e)
    
    def createIndex(self,collection_name,field_name,metric_type,index_type):
        
        index_params = self.client.prepare_index_params()
        
        index_name = "index_"+collection_name

        index_params.add_index(
            field_name=field_name,
            metric_type=metric_type,
            index_type=index_type,
            index_name=index_name,
            params={ "nlist": 128 }
        )

        res = self.client.create_index(
            collection_name=collection_name,
            index_params=index_params
        )
        
        return res
    
    def changeDB(self):
        pass
        
        
    
    
    
